const { verifyJWT } = require('../../util/jwt')
const { useModel } = require('../../model/index')
/**
 * JWT验证器工厂函数。
 * 
 * 该函数返回一个中间件，用于在Koa应用程序中验证JWT令牌。
 * 它可以通过解析令牌来验证用户身份，并在上下文中设置用户信息，以便后续中间件或路由可以使用。
 * 如果令牌无效或不存在，它将返回相应的错误响应。
 * 
 * @param {boolean} isrequire - 是否强制要求JWT令牌。默认为true，表示必须提供令牌。
 * @returns {Function} 返回一个Koa中间件函数。
 */
const jwtValidator = (isrequire = true) => {
    return async (ctx, next) => {
        // 从请求头中获取Authorization信息
        const Beartoken = ctx.get('Authorization')
        // 解析Authorization头，获取JWT令牌
        const token = Beartoken.split(' ')[1]
        if (token) {
            try {
                // 使用verifyJWT函数验证JWT令牌，并解析其中的用户ID
                const { _id } = await verifyJWT(token)
                // 根据用户ID从数据库中查找用户信息
                const dbback = await useModel.findById({ _id })
                if (dbback) {
                    // 如果用户信息存在，将用户信息设置到上下文中，并继续处理后续中间件
                    ctx.userinfo = dbback
                    await next()
                } else {
                    // 如果用户信息不存在，返回401未授权错误
                    ctx.status = 401
                    ctx.body = {
                        error: 1,
                        msg: 'token无效'
                    }
                }
            } catch {
                // 如果验证过程中出现异常，假设为令牌过期，返回401未授权错误
                ctx.status = 401
                ctx.body = {
                    error: 1,
                    msg: 'token过期'
                }
            }
        } else if (isrequire) {
            // 如果要求提供JWT令牌但未提供，则返回401未授权错误
            ctx.status = 401
            ctx.body = {
                error: 1,
                msg: 'token不存在'
            }
        } else {
            // 如果不要求提供JWT令牌，或令牌确实不存在，则直接继续处理后续中间件
            await next()
        }
    }
}

module.exports = jwtValidator